package org.genuflex.components
{
	import mx.containers.TitleWindow;
	import mx.managers.PopUpManager;
	import mx.events.CollectionEvent;
	import mx.collections.ArrayCollection;

	import org.genuflex.utils.GenuflexCairngormHelper;
	import flash.events.Event;
	import org.genuflex.vo.GenuflexValueObject;
	import mx.states.State;
	import mx.states.RemoveChild;
	import mx.states.AddChild;
	import mx.controls.Text;
	import org.genuflex.utils.GenuflexDataFunctions;
	import mx.core.EdgeMetrics;
	import mx.controls.Alert;
	import flash.geom.Rectangle;
	
	public class GenuflexEditWindow extends TitleWindow {
	
		public static var openWindows : ArrayCollection= new ArrayCollection();
		public static var activeWindows : ArrayCollection= new ArrayCollection();
		public static var inactiveWindows : ArrayCollection= new ArrayCollection();
	
		private static var MAX_WINDOWS : int = 2;
				
		[Bindable]			
		public var originalWidth : Number;
		[Bindable] public var originalHeight : Number;
	
		public function GenuflexEditWindow() {
			super();
			
			this.layout = "vertical";
			this.width = NaN;
			this.title="Edit";
		
			addEventListener("creationComplete", onCreationComplete);
			
			//Update state and title
			updateStateAndTitle();
		}
		
		[Bindable]
		protected var currentVO : GenuflexValueObject;
		public function setCurrentVO( value : GenuflexValueObject) : void {
			currentVO = value;
			setTypedVO(currentVO);
			
			//Update state and title
			updateStateAndTitle();
		}
		
		private function updateStateAndTitle() : void {
			currentState = currentVO == null? 'Loading' : (currentVO["id"] > 0 ? null : 'Add');			
			title = currentVO == null? 'Loading ' + objectLabel : (currentVO["id"] > 0 ? objectLabel + ": "+currentVO.getLabel() : "Add "+objectLabel);
		}
		
		public function setTypedVO(value : GenuflexValueObject) : void { /* Meant to be overridden */ }
		
		/* Functions passed in from the calling component */
		public var saveFunction : Function;
		public var cancelFunction : Function;
		
		/* Labels for the objects being managed */
		public var objectLabel : String = "";
		
		protected function onCreationComplete(event : Event) : void {
			PopUpManager.centerPopUp(this);
			
			this.titleBar.doubleClickEnabled = true;			
			this.titleBar.addEventListener("doubleClick", titleBarDoubleClick);
			
			this.originalWidth = NaN;
			arrangeWindows(this, "creation");
			
		}
	  		 
		private static function arrangeWindows(targetWindow : GenuflexEditWindow, mode : String) : void{
			var currX : Number = 0;
			var newWidth : Number = 0;
			var windowCount : int = 0;
			var window : GenuflexEditWindow = null;
			
			//First off, let's figure out what is triggering the arrangement
			switch(mode) {
				case "creation":
					//Add this window to the openWindows and activeWindows
					openWindows.addItem(targetWindow);
					activeWindows.addItem(targetWindow);
					
					//If there are more than MAX_WINDOWS, move one from
					//active to in-active
					if (activeWindows.length > MAX_WINDOWS) {
						window = activeWindows[0] as GenuflexEditWindow;
						inactiveWindows.addItem(window);
						activeWindows.removeItemAt(0);
					}
					break;

				case "minimize":
					//Remove this window from active Windows
					//and add to inactiveWindows
					GenuflexDataFunctions.removeFromArray(activeWindows, targetWindow);
					inactiveWindows.addItem(targetWindow);
					
					//If there are less than MAX_WINDOWS, move one from
					//in-active to active
					if (activeWindows.length < MAX_WINDOWS && inactiveWindows.length > 0) {
						window = inactiveWindows[0] as GenuflexEditWindow;

						//We don't want to activate the window that
						// the user just minimized
						if (window != targetWindow) {
							activeWindows.addItem(window);
							inactiveWindows.removeItemAt(0);
						}

					}
					break;
				case "restore":
					//Remove this window from inactive Windows
					//and add to activeWindows
					GenuflexDataFunctions.removeFromArray(inactiveWindows, targetWindow);
					activeWindows.addItem(targetWindow);
					
					//If there are more than MAX_WINDOWS, move one from
					//active to in-active
					if (activeWindows.length > MAX_WINDOWS) {
						window = activeWindows[0] as GenuflexEditWindow;
						inactiveWindows.addItem(window);
						activeWindows.removeItemAt(0);
					}			
					break;
				case "close":
					//Remove this window from active Windows
					//and add to inactiveWindows
					GenuflexDataFunctions.removeFromArray(activeWindows, targetWindow);
					GenuflexDataFunctions.removeFromArray(inactiveWindows, targetWindow);
					GenuflexDataFunctions.removeFromArray(openWindows, targetWindow);
					
					//If there are less than MAX_WINDOWS, move one from
					//in-active to active
					if (activeWindows.length < MAX_WINDOWS && inactiveWindows.length >0) {
						window = inactiveWindows[0] as GenuflexEditWindow;
						activeWindows.addItem(window);
						inactiveWindows.removeItemAt(0);
					}				
					break;
			}
			
			windowCount = activeWindows.length;
			
			if (windowCount == 1) {
				openWindows[0].width = openWindows[0].originalWidth;
				openWindows[0].height = openWindows[0].originalHeight;
					
				PopUpManager.centerPopUp(openWindows[0]);
			}
			else {
				
				for each(window in activeWindows) {

					window.move(currX, 10);					
							
					currX += window.width;
													
					window.width = window.originalWidth;
					
					//If the window is currently minimized, restore it
					if (window.height == window.titleBar.height) {
						if (isNaN(window.originalHeight)) {
							window.height = window.screen.height - 60;
						}
						else {
							window.height = window.originalHeight;
						}
					}
				}
				
				currX = 0;
				
				if (inactiveWindows.length > 0) {
					newWidth = inactiveWindows[0].screen.width / inactiveWindows.length;
					
					for each(window in inactiveWindows) {
						var screen : Rectangle = window.screen;					
						
						//Grab the original height and width
						if (isNaN(window.originalHeight)) {
							window.originalHeight = window.height;
						}	
	
						//Minimize the window						
						window.height = window.titleBar.height;						
						
						//Squeeze it if necessary
						if (window.width > newWidth) {
							window.width = newWidth;
						}
						
						//Move to the bottom
						window.move(currX, screen.bottom - 40);
						
						currX += window.width;
					}
				}
			}
		}
		
		/*
		 * Handle Minimize/restore on double-click
		 */
		protected function titleBarDoubleClick(event : Event = null) : void {
			if (height != originalHeight && originalHeight >0) {
				arrangeWindows(this, "restore");
			}
			else {
				arrangeWindows(this, "minimize");
			}
		}

		protected function closeWindow() : void {
			PopUpManager.removePopUp(this);		
			arrangeWindows(this, "close");
		}

		/* The user wants out.  Fire cancelFunction and close the window */
		public function handleCancel() : void {

			//If a cancel function was specified, call it first
			if (cancelFunction != null) {
				cancelFunction.call(this);
			}
			
			closeWindow();
		}

		/* Populate the object with user-entered data, fire saveFunction and close the window */
		public function handleSave() : void {

			//If a save function was specified, call it now
			if (saveFunction != null) {
				saveFunction.call(this);
			}
			
			closeWindow();				

		}		

	}
}